package com.migration.service.impl;

import com.migration.model.newdb.RiskChainCause;
import com.migration.model.olddb.RaDeviateReason;
import com.migration.model.olddb.RaFaultChainsDetail;
import com.migration.model.olddb.RaInfluence;
import com.migration.service.RiskChainCauseService;
import com.migration.util.CommonUtils;
import jakarta.persistence.EntityManager;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 事故链-原因表服务实现类
 */
@Service
public class RiskChainCauseServiceImpl implements RiskChainCauseService {

    @Override
    public List<RiskChainCause> migrateCauseData(
            EntityManager oldEntityManager,
            EntityManager newEntityManager,
            List<RaDeviateReason> reasonList,
            Map<Long, Integer> reasonToTenantMap,
            Set<Long> reasonWithConsequenceSet) {

        List<RiskChainCause> causeList = new ArrayList<>();

        for (RaDeviateReason reason : reasonList) {
            // 通过reasonId从reasonToTenantMap中找到对应的租户ID
            Integer tenantId = reasonToTenantMap.get(reason.getId());
            if(tenantId == null){
                continue;
            }

            // 创建RiskChainCause对象
            RiskChainCause cause = new RiskChainCause();
            cause.setId(String.valueOf(reason.getId()));
            cause.setTenantId(1L);
            cause.setDepartmentId(CommonUtils.toLong(tenantId)); // 部门ID使用租户ID

            // 设置分析类型（根据linked_type：1为连续工艺，2为间隙工艺，4为操作）
            if (reason.getLinkedType() != null) {
                if (reason.getLinkedType() == 1) {
                    cause.setAnalysisType(1); // 连续工艺
                    cause.setAnalysisId(reason.getLinkedId());
                } else if (reason.getLinkedType() == 2) {
                    cause.setAnalysisType(2); // 间隙工艺
                    cause.setAnalysisId(reason.getStepDetailId() != null ? reason.getStepDetailId() : 0L);
                } else if (reason.getLinkedType() == 4) {
                    cause.setAnalysisType(3); // JSA操作
                    cause.setAnalysisId(reason.getLinkedId());
                } else {
                    cause.setAnalysisType(1); // 默认为连续工艺
                    cause.setAnalysisId(reason.getLinkedId() != null ? reason.getLinkedId() : 0L);
                }
            } else {
                cause.setAnalysisType(1); // 默认为连续工艺
                cause.setAnalysisId(reason.getLinkedId() != null ? reason.getLinkedId() : 0L);
            }

            // 设置来源ID
            cause.setFromId(reason.getId().toString());

            // 设置原因描述
            if (StringUtils.isEmpty(reason.getCauseDesc())) {
                cause.setCauseDesc("未知原因");
            } else {
                cause.setCauseDesc(reason.getCauseDesc());
            }

            // 设置原因类型
            cause.setCauseType(reason.getCauseType() != null ? reason.getCauseType().intValue() : 0);

            // 设置位号
            cause.setTagNumber(reason.getBitNum());

            // 设置可能性ID
            cause.setLikelihoodId(reason.getProbabilityId() != null ? reason.getProbabilityId() : 1L);

            // 设置是否有后果，通过查询reasonWithConsequenceSet判断
            cause.setHasResult(reasonWithConsequenceSet.contains(reason.getId()));

            // 设置创建时间和更新时间
            cause.setCreateTime(CommonUtils.formatDateTime(reason.getCreateTime()));
            cause.setUpdateTime(CommonUtils.formatDateTime(reason.getUpdateTime()));

            // 设置创建人和更新人
            cause.setCreateBy(1L);
            cause.setUpdateBy(1L);

            // 设置是否删除
            cause.setIsDel(false);

            causeList.add(cause);
            newEntityManager.persist(cause);
        }

        return causeList;
    }

    @Override
    public List<RaDeviateReason> getAllReasons(EntityManager oldEntityManager) {
        CriteriaBuilder oldCriteriaBuilder = oldEntityManager.getCriteriaBuilder();
        CriteriaQuery<RaDeviateReason> reasonQuery = oldCriteriaBuilder.createQuery(RaDeviateReason.class);
        Root<RaDeviateReason> reasonRoot = reasonQuery.from(RaDeviateReason.class);
        reasonQuery.select(reasonRoot);
        reasonQuery.where(oldCriteriaBuilder.equal(reasonRoot.get("isDel"), (byte) 0));
        return oldEntityManager.createQuery(reasonQuery).getResultList();
    }

    @Override
    public Map<Long, Integer> buildReasonToTenantMap(EntityManager oldEntityManager, List<Long> reasonIds) {
        Map<Long, Integer> reasonToTenantMap = new HashMap<>();

        if (!reasonIds.isEmpty()) {
            // 分批查询，避免IN子句过长
            int batchSize = 500;
            CriteriaBuilder oldCriteriaBuilder = oldEntityManager.getCriteriaBuilder();

            for (int i = 0; i < reasonIds.size(); i += batchSize) {
                int endIndex = Math.min(i + batchSize, reasonIds.size());
                List<Long> batchIds = reasonIds.subList(i, endIndex);

                CriteriaQuery<RaInfluence> batchInfluenceCq = oldCriteriaBuilder.createQuery(RaInfluence.class);
                Root<RaInfluence> batchInfluenceRoot = batchInfluenceCq.from(RaInfluence.class);

                // 构建查询条件：reason_id在batchIds中，且未删除
                jakarta.persistence.criteria.Predicate reasonIdIn = batchInfluenceRoot.get("reasonId").in(batchIds);
                jakarta.persistence.criteria.Predicate notDeletedInfluence = oldCriteriaBuilder.equal(batchInfluenceRoot.get("isDel"), (byte) 0);
                batchInfluenceCq.where(oldCriteriaBuilder.and(reasonIdIn, notDeletedInfluence));

                List<RaInfluence> influenceBatchList = oldEntityManager.createQuery(batchInfluenceCq).getResultList();

                // 使用merge函数处理重复键，这里我们保留最新的值
                Map<Long, Integer> batchMap = influenceBatchList.stream()
                        .collect(Collectors.toMap(
                                influence -> influence.getReasonId(),
                                influence -> influence.getTenantId(),
                                (oldValue, newValue) -> newValue)); // 如果有重复键，保留新值

                // 将批次结果合并到reasonToTenantMap
                reasonToTenantMap.putAll(batchMap);
            }
        }

        return reasonToTenantMap;
    }

    @Override
    public Set<Long> buildReasonWithConsequenceSet(List<RaFaultChainsDetail> detailList) {
        Set<Long> reasonWithConsequenceSet = new HashSet<>();

        // 将已知有后果的原因ID加入集合
        for (RaFaultChainsDetail detail : detailList) {
            if (detail.getReasonId() != null && detail.getConsequenceId() != null) {
                reasonWithConsequenceSet.add(detail.getReasonId());
            }
        }

        return reasonWithConsequenceSet;
    }
}
